package com.mine.controller;

import com.mine.jzh.SysEnum;
import com.mine.jzh.mapper.SysEnumMapper;
import com.mine.jzh3.oss.AliOSSOperation;
import com.mine.jzh3.oss.utils.FileConverter;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * OSS文件存储控制器
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/api/oss")
public class OssController {

    private final AliOSSOperation aliOSSOperation;
    private final SysEnumMapper sysEnumMapper;

    /**
     * 上传单个文件
     */
    @PostMapping("/upload")
    public ResponseEntity<UploadResponse> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            String fileName =
                    UUID.randomUUID() + FileConverter.getExtension(file.getOriginalFilename());
            SysEnum sysEnum = sysEnumMapper.selectByDictCodeAndCode("images", "jzh");

            String fileUrl = aliOSSOperation.uploadFile(sysEnum.getRemark1(), file.getInputStream(),
                                                        sysEnum.getRemark2() + fileName);

            return ResponseEntity.ok(UploadResponse.success(file.getOriginalFilename(), fileUrl));
        } catch (IOException e) {
            log.error("文件上传失败", e);
            return ResponseEntity
                    .internalServerError()
                    .body(UploadResponse.error(file.getOriginalFilename(), e.getMessage()));
        }
    }

    /**
     * 上传多个文件
     */
    @PostMapping("/batch-upload")
    public ResponseEntity<List<UploadResponse>> uploadFiles(@RequestParam("files") MultipartFile[] files) {
        List<UploadResponse> responses = new ArrayList<>();
        SysEnum sysEnum = sysEnumMapper.selectByDictCodeAndCode("images", "jzh");

        for (MultipartFile file : files) {
            try {
                String fileName =
                        UUID.randomUUID() + FileConverter.getExtension(file.getOriginalFilename());
                String fileUrl = aliOSSOperation.uploadFile(sysEnum.getRemark1(), file.getInputStream()
                        , sysEnum.getRemark2() + fileName);
                responses.add(UploadResponse.success(file.getOriginalFilename(), fileUrl));
            } catch (IOException e) {
                log.error("文件上传失败", e);
                responses.add(UploadResponse.error(file.getOriginalFilename(), e.getMessage()));
            }
        }
        return ResponseEntity.ok(responses);
    }

    /**
     * 上传Base64编码的文件
     */
    @PostMapping("/upload-base64")
    public ResponseEntity<UploadResponse> uploadBase64(@RequestBody Base64UploadRequest request) {
        try {
            String fileName = UUID.randomUUID() + FileConverter.getExtension(request.getFileName());
            SysEnum sysEnum = sysEnumMapper.selectByDictCodeAndCode("images", "jzh");

            String fileUrl = aliOSSOperation.uploadFile(sysEnum.getRemark1(),
                                                        FileConverter.fromBase64(request.getBase64Data()), sysEnum.getRemark2() + fileName);

            return ResponseEntity.ok(UploadResponse.success(request.getFileName(), fileUrl));
        } catch (Exception e) {
            log.error("Base64文件上传失败", e);
            return ResponseEntity
                    .internalServerError()
                    .body(UploadResponse.error(request.getFileName(), e.getMessage()));
        }
    }

    /**
     * 删除文件
     */
    @DeleteMapping("/{objectName}")
    public ResponseEntity<String> deleteFile(@PathVariable String objectName) {
        try {
            SysEnum sysEnum = sysEnumMapper.selectByDictCodeAndCode("images", "jzh");
            aliOSSOperation.deleteFile(sysEnum.getRemark1(), sysEnum.getRemark2() + objectName);
            return ResponseEntity.ok("文件删除成功");
        } catch (Exception e) {
            log.error("文件删除失败", e);
            return ResponseEntity
                    .internalServerError()
                    .body("文件删除失败：" + e.getMessage());
        }
    }

    /**
     * 获取文件URL
     */
    @GetMapping("/url/{objectName}")
    public ResponseEntity<String> getFileUrl(@PathVariable String objectName) {
        try {
            SysEnum sysEnum = sysEnumMapper.selectByDictCodeAndCode("images", "jzh");
            String fileUrl = aliOSSOperation.getFileUrl(sysEnum.getRemark1(),
                                                        sysEnum.getRemark2() + objectName);
            return ResponseEntity.ok(fileUrl);
        } catch (Exception e) {
            log.error("获取文件URL失败", e);
            return ResponseEntity
                    .internalServerError()
                    .body("获取文件URL失败：" + e.getMessage());
        }
    }

    /**
     * 下载文件
     */
    @GetMapping("/download/{objectName:.+}")
    public ResponseEntity<byte[]> downloadFile(@PathVariable String objectName) {
        try {
            // URL解码
            String decodedObjectName = java.net.URLDecoder.decode(objectName, "UTF-8");
            SysEnum sysEnum = sysEnumMapper.selectByDictCodeAndCode("images", "jzh");
            decodedObjectName = sysEnum.getRemark2() + decodedObjectName;

            log.info("下载文件: objectName={}, decodedObjectName={}", objectName, decodedObjectName);

            // 获取文件内容
            byte[] fileContent = aliOSSOperation.safeDownloadFile(sysEnum.getRemark1(),
                                                              decodedObjectName);
            if (fileContent == null || fileContent.length == 0) {
                return ResponseEntity.notFound().build();
            }

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            // 设置文件名，使用URL编码
            String encodedFileName = java.net.URLEncoder
                    .encode(decodedObjectName.substring(decodedObjectName.lastIndexOf("/") + 1), "UTF-8");
            headers.setContentDispositionFormData("attachment", encodedFileName);

            return ResponseEntity
                    .ok()
                    .headers(headers)
                    .body(fileContent);
        } catch (Exception e) {
            log.error("文件下载失败: objectName={}", objectName, e);
            return ResponseEntity
                    .internalServerError()
                    .build();
        }
    }

    /**
     * 列出文件
     */
    @GetMapping("/list")
    public ResponseEntity<List<String>> listFiles(@RequestParam(required = false) String prefix) {
        try {
            SysEnum sysEnum = sysEnumMapper.selectByDictCodeAndCode("images", "jzh");
            List<String> files = aliOSSOperation.listFiles(sysEnum.getRemark1(), prefix != null ?
                    sysEnum.getRemark2() + prefix : sysEnum.getRemark2());
            return ResponseEntity.ok(files);
        } catch (Exception e) {
            log.error("列出文件失败", e);
            return ResponseEntity
                    .internalServerError()
                    .build();
        }
    }

    @Data
    public static class Base64UploadRequest {
        private String base64Data;
        private String fileName;
        private String fileType;
    }

    @Data
    public static class UploadResponse {
        private String fileName;
        private String fileUrl;
        private String error;

        public static UploadResponse success(String fileName, String fileUrl) {
            UploadResponse response = new UploadResponse();
            response.setFileName(fileName);
            response.setFileUrl(fileUrl);
            return response;
        }

        public static UploadResponse error(String fileName, String error) {
            UploadResponse response = new UploadResponse();
            response.setFileName(fileName);
            response.setError(error);
            return response;
        }
    }
}
